package pcb.views 
{
	import com.intel.core.Application;
	import com.intel.core.UIComponent;
	import com.intel.patterns.observer.IObserver;
	import com.intel.patterns.observer.Subject;
	import com.intel.utils.Debugger;
	import com.intel.utils.TransitionManager;
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.utils.getTimer;
	import pcb.control.events.InteractionEvent;
	import pcb.control.events.LessonEvent;
	import pcb.control.events.LoadDataEvent;
	import pcb.models.LessonStateModel;
	import pcb.models.LocaleModel;
	import pcb.models.MainMenuModel;
	import pcb.models.Notifications;
	import pcb.models.PlayerSettings;
	import pcb.models.PlayerStateModel;
	import pcb.models.vo.Interaction;
	import pcb.models.vo.IPage;
	import pcb.models.vo.PageTypes;
	import pcb.models.vo.Slide;
	import pcb.models.ModelLocator;
	import pcb.views.uievents.SlideEvent;
	import pcb.views.uievents.UIEvent;
	import com.intel.utils.TextRender;
	
	/**
	 * ...
	 * @author Fintan Boyle
	 */
	public class ViewMediator extends UIComponent implements IObserver 
	{
		private var navGUI:NavGUI;
		private var contentScreen:ContentScreen;
		private var statusScreen:StatusScreen;
		private var loaderScreen:MovieClip;
		private var lessonOverScreen:LessonOverView;
		private var mainMenu:LessonMenu;
		//private var legalScreen:LegalScreen;
		private var messageScreen:MessagesScreen;
		private var moduleInfoScreen:ModuleInfoScreen;
		
		//simple presentation model
		private var currentLessonId:String;
		private var currentLessonName:String = "";
		private var isMuted:Boolean;
		
		protected static var models:ModelLocator = ModelLocator.getInstance();
		
		public function ViewMediator() 
		{
			setupListeners();
		}
		
		
		/**
		 * Creates and adds the nested views.
		 * (called in UIComponent constructor)
		 */
		override protected function addChildren():void
		{
			
			messageScreen = new MessagesScreen();
			
			navGUI = new NavGUI();
			navGUI.x = 0;//tmp
			addChild(navGUI);
			statusScreen = new StatusScreen();
			statusScreen.x = 200;
			statusScreen.y = 60;
			addChild(statusScreen);
			contentScreen = new ContentScreen();
			
			var contentWaypoint:DisplayObject = this.getAppRoot().getChildByName("contentAreaWaypoint") as MovieClip;
			var loadingWaypoint:DisplayObject = this.getAppRoot().getChildByName("loadingWaypoint") as MovieClip;
			var menuWaypoint:DisplayObject = this.getAppRoot().getChildByName("mainMenuWaypoint") as MovieClip;
			
			
			if (contentWaypoint) {
				contentScreen.x = contentWaypoint.x;
				contentScreen.y = contentWaypoint.y;
			}else {
				contentScreen.x = 85;
				contentScreen.y = 100;
			}
			
			addChild(contentScreen);
			
			
			lessonOverScreen = new LessonOverView();
			
			if (contentWaypoint) {
				lessonOverScreen.x = contentWaypoint.x;
				lessonOverScreen.y = contentWaypoint.y;
			}
			
			loaderScreen = new LoaderGraphic_mc() as MovieClip;
			
			if (loadingWaypoint) {
				loaderScreen.x = loadingWaypoint.x;
				loaderScreen.y = loadingWaypoint.y;
			}else {
				var p:Point = Application.getOrigin();
				loaderScreen.x = (this.getAppRoot().stage.stageWidth / 2) - p.x;
				loaderScreen.y = (this.getAppRoot().stage.stageHeight / 2) - p.y;
			}
			
			if(models.playerSettings.useMainMenu) {
				
				if (menuWaypoint) {
					mainMenu = new LessonMenu();
					mainMenu.x = menuWaypoint.x;
					mainMenu.y = menuWaypoint.y;
					addChild(mainMenu);
				}
			}
		}
		
		private function setupListeners():void 
		{
			//child view events will bubble for mediation and communicating with Controller
			this.addEventListener(UIEvent.CLICKED, navGUI_onClicked, false, 0, true);
			if(mainMenu != null) {
				mainMenu.addEventListener(UIEvent.MENU_ITEM_CLICKED, mainMenu_onItemClicked, false, 0, true);
				mainMenu.addEventListener(UIEvent.MENU_NO_ITEM_CLICKED, mainMenu_onNoItemClicked, false, 0, true);
			}
			contentScreen.addEventListener(SlideEvent.COMPLETE, contentScreen_onSlideComplete, false, 0, true);
			contentScreen.addEventListener(Interaction.COMPLETE, contentScreen_onInteractivityComplete, false, 0, true);
		}
		
		
		/* INTERFACE com.intel.patterns.observer.IObserver */
		
		public function update(o:Subject, infoObj:Object):void
		{			
			//ViewMediator will be notified of model updates using Observer pattern
			
			if (infoObj.datatype == Notifications.LESSON_STATUS_CHANGED) {
				
				var lessonState:LessonStateModel = LessonStateModel(o);

				Debugger.traceOut("Mediator view notified of LESSON_STATUS_CHANGED change... " + lessonState.status);
				
				if (lessonState.status == LessonStateModel.PREINITIALISED) {
					
					addChild(loaderScreen);
					
					enableDisableControls(lessonState);
					//dull out all controls
					navGUI.preInitialise();
					
					currentLessonId = lessonState.lessonId;
					
				}else if (lessonState.status == LessonStateModel.INITIALISED) {
					
					if (loaderScreen.parent) removeChild(loaderScreen);
					
					navGUI.initialised();
					
					enableDisableControls(lessonState);
					
					contentScreen.addMainStage(lessonState.mainStage);
					currentLessonName = lessonState.getCurrentLessonTitle();
					TextRender.createLabel(statusScreen.lessonTitleTxt, currentLessonName);
					
					if (lessonOverScreen.parent) removeChild(lessonOverScreen);
					
					/*mainMenu.enableMenu = true;
					mainMenu.enableNextButton(true);
					mainMenu.enablePrevButton(true);*/
					
					
				}else if (lessonState.status == LessonStateModel.NEXT_SLIDE || lessonState.status == LessonStateModel.PREVIOUS_SLIDE) {
					
					enableDisableControls(lessonState);
					if(statusScreen.slideIdTxt) statusScreen.slideIdTxt.text = lessonState.currentSlideIndex + " / " + lessonState.getTotalSlides();
					
				}else if (lessonState.status == LessonStateModel.LOADING_SLIDE) {
					
					//dull out play/pause button and stop button
					navGUI.enablePlayandStop(false);
					addChild(loaderScreen);
					Debugger.traceOut("LessonStateModel.LOADING_SLIDE");
					
				}else if (lessonState.status == LessonStateModel.END_OF_SLIDE) {
					
					Debugger.traceOut("LessonStateModel.END_OF_SLIDE");
					
					navGUI.nextSlideButtonPrompt(true);
					
				}else if (lessonState.status == LessonStateModel.PLAYING) {
					
					if (lessonOverScreen.parent) removeChild(lessonOverScreen);
					if(!contentScreen.parent) addChild(contentScreen);
					
					if(loaderScreen.parent) removeChild(loaderScreen);
					Debugger.traceOut("LessonStateModel.PLAYING");
					contentScreen.update(o, infoObj);
					navGUI.enablePlayandStop(true);
					navGUI.playAndStopStatus(true, false);
					
					navGUI.enableShowMe((lessonState.currentPage as Slide).getPedagogy() == Slide.INTERACTIVE)
					/*
					var isTry:Boolean = false;
					var s:Slide = lessonState.currentPage as Slide;
					
					if (s != null) {						
						if (s.getPedagogy() == Slide.INTERACTIVE) {
							isTry = true;
						}
					}			
					navGUI.enableShowMe(isTry);
					*/
					if (lessonState.currentPage.getPageType() == PageTypes.END_OF_LESSON) {
						showEndOfLesson();
					}
					if(mainMenu != null) {
						mainMenu.enableMenu = true;
						mainMenu.enableNextButton(true);
						mainMenu.enablePrevButton(true);
					}
					
				}else if (lessonState.status == LessonStateModel.STOPPED) {
					Debugger.traceOut("LessonStateModel.STOPPED");
					navGUI.playAndStopStatus(false, true);
					statusScreen.slideIdTxt.text = "";
					contentScreen.update(o, infoObj);
					enableDisableControls(lessonState);
				}else if (lessonState.status == LessonStateModel.PAUSED) {
					Debugger.traceOut("LessonStateModel.PAUSED");
					navGUI.playAndStopStatus(false, false);
					contentScreen.update(o, infoObj);
				}else if (lessonState.status == LessonStateModel.LESSON_FINISHED) {
					Debugger.traceOut("LessonStateModel.LESSON_FINISHED");
				} else if (lessonState.status == LessonStateModel.NEXT_INTERACTIVITY) {
					Debugger.traceOut("LessonStateModel.NEXT_INTERACTIVITY");
					contentScreen.update(o, infoObj);					
				}
				
				statusScreen.slideStatusTxt.text = lessonState.status;
				
			}else if (infoObj.datatype == Notifications.NEW_LESSON_SELECTED) {
				Debugger.traceOut("Notifications.NEW_LESSON_SELECTED");				
				TextRender.createLabel(statusScreen.lessonTitleTxt, "");
				addChild(loaderScreen);
				var lessId:String = PlayerStateModel(o).currentLessonId;
				//mainMenu.selectNode(lessId);
				
				Debugger.traceOut("lessId " + lessId);
				loadNewLesson(lessId);
				
			}else if (infoObj.datatype == Notifications.ASSET_MODEL_CALLING) {
				
				contentScreen.update(o, infoObj);
			}else if (infoObj.datatype == Notifications.MUTE_AUDIO_SET) {
				
				isMuted = PlayerStateModel(o).isMuted;
				contentScreen.update(o, infoObj);
				
			}else if (infoObj.datatype == Notifications.PLAY_AUDIO_SET) {
				Debugger.traceOut("Notifications.PLAY_AUDIO_SET");
				contentScreen.update(o, infoObj);
			}else if (infoObj.datatype == Notifications.NEW_MENU_XML) {
				Debugger.traceOut("Notifications.NEW_MENU_XML");

				if(mainMenu != null) {
					mainMenu.createMenu(MainMenuModel(o).getMenuRSL(), MainMenuModel(o).getMenuXml());
				}
				//mainMenu.selectNode(currentLessonId);
			}else if (infoObj.datatype == Notifications.DISPLAY_EULA) {
				
				Debugger.traceOut("Notifications.DISPLAY_EULA " + messageScreen);
				
				addChild(messageScreen);
				messageScreen.showEula();
				
			}else if (infoObj.datatype == Notifications.NOT_AN_INTEL_PROCESSOR) {
				
				Debugger.traceOut("Notifications.NOT_AN_INTEL_PROCESSOR");
					
				addChild(messageScreen);
				messageScreen.intelProcessorWarning();
				
			}else if (infoObj.datatype == Notifications.SET_FROM_CONFIG) {
				
				Debugger.traceOut("Notifications.SET_FROM_CONFIG");
				
				var playerSettings:PlayerSettings = PlayerSettings(o);
				navGUI.hidePlaythroughControl(playerSettings.hideSlideTransitionControl);
				navGUI.autoPlaythrough(playerSettings.autoSlideTransition);
				navGUI.hideQuit(playerSettings.deployment == "web");
				
				if(!playerSettings.autoStartLesson)if(loaderScreen.parent) removeChild(loaderScreen);
				//todo display a welcome screen
			}else if (infoObj.datatype == Notifications.PLAYER_LOCALE_READY) {
				
				Debugger.traceOut("Notifications.PLAYER_LOCALE_READY");
				var localeModel:LocaleModel = LocaleModel(o);
				navGUI.localiseLabels(localeModel);
				if(mainMenu != null) {
					mainMenu.localiseLabels(localeModel);
				}				
				messageScreen.localiseLabels(localeModel);
				lessonOverScreen.localiseLabels(localeModel);
				
			}
		}
		
		private function enableDisableControls(state:LessonStateModel):void 
		{
			navGUI.prevAndNextStatus(state.onFirstSlide, state.onLastSlide);			
		}
		
		private function createModuleTitleDisplay(moduleTitle:String, sectionTitle:String=""):void 
		{
			removeModuleTitleDisplay();
			
			moduleInfoScreen = new ModuleInfoScreen();
			moduleInfoScreen.setModuleTitle(moduleTitle);
			moduleInfoScreen.setSectionTitle(sectionTitle);
			moduleInfoScreen.gotoCourseImage(ModelLocator.getInstance().playerSettings.course);
			
			var moduleTitleWaypoint:MovieClip = this.getAppRoot().getChildByName("moduleTitleWaypoint") as MovieClip;
			if (moduleTitleWaypoint) {
				moduleInfoScreen.x = moduleTitleWaypoint.x;
				moduleInfoScreen.y = moduleTitleWaypoint.y;
			}else {
				moduleInfoScreen.x = this.getAppRoot().stage.stageWidth / 2;
				moduleInfoScreen.y = this.getAppRoot().stage.stageHeight / 2;
			}
			addChild(moduleInfoScreen);
		}
		
		private function removeModuleTitleDisplay():void 
		{
			if (moduleInfoScreen) if (moduleInfoScreen.parent) {
				moduleInfoScreen.parent.removeChild(moduleInfoScreen);
				moduleInfoScreen = null;
			}
		}
		
		private function showEndOfLesson():void 
		{
			navGUI.playAndStopStatus(false, true);
			navGUI.prevAndNextStatus(false, true);	
			
			lessonOverScreen.setCurrentLesson(currentLessonName);
			
			addChild(lessonOverScreen);
			//contentScreen.setVoText("");
		}
		
		/**
		 * sets mainstage to null amongst other things
		 */
		private function closeCurrentLesson():void 
		{
			var evResetLessonState:LessonEvent = new LessonEvent(LessonEvent.CLEAR_LESSON);
			evResetLessonState.dispatch();
			
			if (lessonOverScreen.parent) removeChild(lessonOverScreen);
			
			contentScreen.preInitialise();
			statusScreen.preInitialise();
			//navGUI.preInitialise();
		}
		
		private function navGUI_onClicked(e:UIEvent):void 
		{
			Debugger.traceOut("viewMediator >> "+ e.id);
			if (e.id == "previous") {
				//previous slide
				var evP:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evP.data = "previous";
				evP.dispatch();
			} 
			else if (e.id == "quit") {
				//Quit
				var evQ:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evQ.data = "quit";
				evQ.dispatch();

			}
			else if (e.id == "next") {
				//next slide
				var evN:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evN.data = "next";
				evN.dispatch();
				
			}else if (e.id == "next-lesson") {
				//next lesson
				var evNL:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evNL.data = "next-lesson";
				evNL.dispatch();
				
			}else if (e.id == "previous-lesson") {
				//previous lesson
				var evPL:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evPL.data = "previous-lesson";
				evPL.dispatch();
			}else if (e.id == "play") {
				var evPl:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evPl.data = "play";
				evPl.dispatch();
			}else if (e.id == "stop") {
				var evS:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evS.data = "stop";
				evS.dispatch();
			}else if (e.id == "replay") {
				
				contentScreen.stopCurrentSound();
				var evR:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evR.data = "replay";
				evR.dispatch();
				
			}else if (e.id == "pause") {
				var evPause:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evPause.data = "pause";
				evPause.dispatch();
			} else if (e.id == "sound_on") {
				contentScreen.mutePage(false);
				
				var evSoundOn:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evSoundOn.data = "sound_on";
				evSoundOn.dispatch();
				
			} else if (e.id == "sound_off") {
				contentScreen.mutePage(true);
				
				var evSoundOff:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evSoundOff.data = "sound_off";
				evSoundOff.dispatch();
				
			} else if (e.id == "votext_on") {
				contentScreen.showVoText(true);
			} else if (e.id == "votext_off") {
				contentScreen.showVoText(false);
			} else if (e.id == "show_me") {
				contentScreen.showMe();
			} else if (e.id == "auto-slide-transition-on") {
				var evTransOn:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evTransOn.data = "auto-slide-transition-on";
				evTransOn.dispatch();
			}else if (e.id == "auto-slide-transition-off") {
				var evTransOff:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evTransOff.data = "auto-slide-transition-off";
				evTransOff.dispatch();
			} else if (e.id == "eula-agreed-to-terms" || e.id == "eula-disagreed-to-terms") {
				
				if (messageScreen) if (messageScreen.parent) {
					removeChild(messageScreen);
					//messageScreen = null;
				}
				
				var evEula:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evEula.data = e.id;
				evEula.dispatch();
				
			}else if (e.id == "show_legal") {
				
				var evStop:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evStop.data = "stop";
				evStop.dispatch();
				
				var evLegal:InteractionEvent = new InteractionEvent(InteractionEvent.USER_GESTURE);
				evLegal.data = e.id;
				evLegal.dispatch();
				
			} else {
				Debugger.traceOut("Gesture not handled in : viewMediator" + e.id, Debugger.WARNING);
			}
		}
		
		private function contentScreen_onSlideComplete(e:Event):void 
		{
			var evSlideComplete:LessonEvent = new LessonEvent(LessonEvent.SLIDE_COMPLETE);
			evSlideComplete.dispatch();
			
			//navGUI.nextSlideButtonPrompt(true);
		}
		
		private function contentScreen_onInteractivityComplete(e:Event):void 
		{
			var evSlideComplete:LessonEvent = new LessonEvent(LessonEvent.INTERACTIVITY_COMPLETED);
			evSlideComplete.dispatch();
		}
		
		private function mainMenu_onItemClicked(e:UIEvent):void 
		{
			loadNewLesson(e.id);
			navGUI.preInitialise();
			navGUI.enableVoText(true);
			contentScreen.showVoText(true);
		}
		
		
		private function mainMenu_onNoItemClicked(e:UIEvent):void 
		{
			
			closeCurrentLesson();
			var ancestryChain:Array = String(e.data).split(",");
			if (ancestryChain.length > 1) {
				createModuleTitleDisplay(ancestryChain[1],ancestryChain[0]);
			}else if (ancestryChain.length == 1) {
				createModuleTitleDisplay(ancestryChain[0]);
			}
			navGUI.preInitialise();
			navGUI.enableVoText(false);
			contentScreen.showVoText(false);
			
		}
		
		private function loadNewLesson(id:String):void 
		{
			
			//TODO align direct menu_item click to how I am doing prev and next lesson
			closeCurrentLesson();
			removeModuleTitleDisplay();
			addChild(loaderScreen);
			
			var ev:LoadDataEvent = new LoadDataEvent(LoadDataEvent.RETRIEVE_LESSON_ID);
			ev.data = id;
			ev.dispatch();
			
		}
		
		
	}
	
}